package com.aj.activity.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewTreeObserver;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.Scroller;

import com.aj.activity.R;

/**
 * 可以下拉刷新的View 现在不具有扩展性，子view必须有scrollview Created by liwei on 14-8-5.
 */

public class PullToRefreshView extends LinearLayout {

	// 刷新状态
	private static final int PULL_TO_REFRESH = 2;
	private static final int RELEASE_TO_REFRESH = 3;
	private static final int REFRESHING = 4;

	// header，显示当前的刷新状态
	private ScrollViewHeader mHeaderView;
	private RelativeLayout mHeaderViewContent;

	// header的高度，固定值，在初始话时获取此值
	private int mHeaderViewHeight;

	// 刷新状态
	private int mHeaderState;

	// 子View，现在必须为ScrollView
	private ScrollView mScrollView;

	// 刷新的Listener，当满足刷新条件时触发
	private OnRefreshListener mRefreshListener;

	private int mTouchSlop;

	public PullToRefreshView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	public PullToRefreshView(Context context) {
		super(context);
		init(context);
	}

	private void init(Context context) {
		// 需要设置成vertical
		setOrientation(LinearLayout.VERTICAL);

		final ViewConfiguration configuration = ViewConfiguration.get(context);
		mTouchSlop = configuration.getScaledTouchSlop();

		mHeaderView = new ScrollViewHeader(context);
		mHeaderViewContent = (RelativeLayout) mHeaderView
				.findViewById(R.id.xlistview_header_content);

		LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT,
				LayoutParams.WRAP_CONTENT);
		addView(mHeaderView, params);

		mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener(
				new ViewTreeObserver.OnGlobalLayoutListener() {
					@Override
					public void onGlobalLayout() {
						mHeaderViewContent.measure(0, 0);
						mHeaderViewHeight = mHeaderViewContent
								.getMeasuredHeight();
						getViewTreeObserver()
								.removeGlobalOnLayoutListener(this);
					}
				});
	}

	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();
		initScrollView();
	}

	private void initScrollView() {
		for (int i = 0; i < getChildCount(); ++i) {
			View view = getChildAt(i);
			if (view instanceof ScrollView) {
				mScrollView = (ScrollView) view;
				return;
			}
		}
	}

	private int mLastMotionY;

	@Override
	public boolean onInterceptTouchEvent(MotionEvent e) {
		int y = (int) e.getRawY();
		switch (e.getAction()) {
		case MotionEvent.ACTION_DOWN:
			// 首先拦截down事件,记录y坐标
			mLastMotionY = y;
			break;
		case MotionEvent.ACTION_MOVE:
			int deltaY = y - mLastMotionY;
			if (Math.abs(deltaY) > mTouchSlop) {
				// deltaY > 0 是向下运动,< 0是向上运动
				mLastMotionY = y;
				return isRefreshViewScroll(deltaY);
			}
			break;
		case MotionEvent.ACTION_UP:
			break;
		case MotionEvent.ACTION_CANCEL:
			break;
		}
		return false;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		int y = (int) event.getRawY();
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			break;
		case MotionEvent.ACTION_MOVE:
			int deltaY = y - mLastMotionY;
			mLastMotionY = y;
			headerPrepareToRefresh(deltaY);
			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_CANCEL:
			if (mHeaderState == REFRESHING) {
				// 刷新过程中如果下拉过度，返回到正常刷新中
				if (getHeaderTopMargin() >= 0) {
					updateHeaderViewTopMargin(0, true);
				}
			} else {
				int topMargin = getHeaderTopMargin();
				if (topMargin >= 0) {
					// 开始刷新
					headerRefreshing();
				} else if (topMargin < 0 && topMargin > -mHeaderViewHeight) {
					// 还没有执行刷新，重新隐藏
					updateHeaderViewTopMargin(-mHeaderViewHeight, true);
				} else {
				}
			}
			break;
		}
		return super.onTouchEvent(event);
	}

	/**
	 * 是否应该到了父View,即PullToRefreshView滑动
	 */
	private boolean isRefreshViewScroll(int deltaY) {
		if (mHeaderView.getVisiableHeight() > 0) {
			return true;
		} else if (deltaY > 0 && mScrollView.getScrollY() == 0) {
			return true;
		} else {
			return false;
		}
	}

	private void headerPrepareToRefresh(int deltaY) {
		if (Math.abs(deltaY) < 2) {
			deltaY = deltaY * 2;
		}
		int topMargin = (int) (deltaY * 0.8f) + mHeaderView.getVisiableHeight()
				- mHeaderViewHeight;
		updateHeaderViewTopMargin(topMargin, false);
	}

	private void updateHeaderViewTopMargin(int topMargin, boolean isScroll) {
		int endHeaderHeight = mHeaderViewHeight + topMargin;

		if (mHeaderState != REFRESHING) {
			if (endHeaderHeight > mHeaderViewHeight) {
				mHeaderView.setState(XListViewHeader.STATE_READY);
				mHeaderState = RELEASE_TO_REFRESH;
			} else {
				mHeaderView.setState(XListViewHeader.STATE_NORMAL);
				mHeaderState = PULL_TO_REFRESH;
			}
		}

		if (isScroll) {
			mHeaderView.startScroll(mHeaderView.getVisiableHeight(),
					mHeaderViewHeight + topMargin);
		} else {
			mHeaderView.setVisiableHeight(mHeaderViewHeight + topMargin);
		}
	}

	private void headerRefreshing() {
		if (mRefreshListener != null) {
			mHeaderState = REFRESHING;
			updateHeaderViewTopMargin(0, true);
			mHeaderView.setState(XListViewHeader.STATE_REFRESHING);
			mRefreshListener.OnRefresh();
		} else {
			onRefreshComplete();
		}
	}

	public void onRefreshComplete() {
		updateHeaderViewTopMargin(-mHeaderViewHeight, true);
		mHeaderView.setState(XListViewHeader.STATE_NORMAL);
		mHeaderState = PULL_TO_REFRESH;
	}

	private int getHeaderTopMargin() {
		return mHeaderView.getVisiableHeight() - mHeaderViewHeight;
	}

	public void setOnRefreshListener(OnRefreshListener refreshListener) {
		mRefreshListener = refreshListener;
	}

	public interface OnRefreshListener {
		public void OnRefresh();
	}

	/**
	 * 可以设置滑动效果的Header
	 */
	private class ScrollViewHeader extends XListViewHeader {

		private Scroller mScroller;
		private final static int SCROLL_DURATION = 400;

		public ScrollViewHeader(Context context) {
			super(context);
			init();
		}

		public ScrollViewHeader(Context context, AttributeSet attrs) {
			super(context, attrs);
			init();
		}

		private void init() {
			mScroller = new Scroller(getContext());
		}

		@Override
		public void computeScroll() {
			if (mScroller.computeScrollOffset()) {
				mHeaderView.setVisiableHeight(mScroller.getCurrY());
				postInvalidate();
			}
			super.computeScroll();
		}

		public void startScroll(int begin, int end) {
			mScroller.startScroll(0, begin, 0, end - begin, SCROLL_DURATION);
			invalidate();
		}
	}
}
